package com.wys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wys.dao.DishDao;
import com.wys.dto.DishDto;
import com.wys.exception.CustomerException;
import com.wys.pojo.Category;
import com.wys.pojo.Dish;
import com.wys.pojo.DishFlavor;
import com.wys.pojo.SetmealDish;
import com.wys.result.R;
import com.wys.service.CategoryService;
import com.wys.service.DishFlavorService;
import com.wys.service.DishService;
import com.wys.service.SetmealDishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishDao, Dish> implements DishService {
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 新增菜品
     * @param dishDto
     */
    @Override
    @Transactional()
    public void insert(DishDto dishDto) {
        //保存菜品
        save(dishDto);
        //得到菜品ID
        Long dishId = dishDto.getId();
        //菜品口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().map((item) ->{
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());
        //保存菜品口味
        dishFlavorService.saveBatch(flavors);
    }
    /**
     *  菜品分页查询
     * @param page 当前页
     * @param pageSize  页面大小
     * @param name 要查询的菜品名称
     * @return
     */
    @Override
    public Page getPage(int page, int pageSize, String name) {
        //分页构造器
        Page<Dish> pageInfo = new Page<>(page,pageSize);
        //条件查询构造器
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        //添加按名字查询菜品的条件
        wrapper.like(name != null,Dish::getName,name);
        //添加排序条件
        wrapper.orderByDesc(Dish::getUpdateTime);
        page(pageInfo,wrapper);
        //带菜品名称
        Page<DishDto> dtoPage =new Page<>();
        //将pageInfo中的数据拷贝到dtoPage中,忽略records属性
        BeanUtils.copyProperties(pageInfo,dtoPage,"records");
        //将pageInfo中的数据拿出来，加上菜品分类名称，在重新赋给dtoPage
        List<Dish> records = pageInfo.getRecords();
        List<DishDto> dishDtoList = records.stream().map((item) ->{
            DishDto dishDto=new DishDto();
            BeanUtils.copyProperties(item,dishDto);
            //菜品分类ID
            Long id = item.getCategoryId();
            Category category = categoryService.getById(id);
            if (category != null){
                dishDto.setCategoryName(category.getName());
            }

            return dishDto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(dishDtoList);
        return dtoPage;
    }

    /**
     * 根据Id查询时数据，并在页面进行数据回显
     * @param id
     * @return
     */
    @Override
    public DishDto getByIdWithFlavor(Long id) {
        DishDto dishDto = new DishDto();
        //查询该菜品的口味集合
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId,id);
        List<DishFlavor> dishFlavorList = dishFlavorService.list(wrapper);
        dishDto.setFlavors(dishFlavorList);
        //根据id查询菜品
        Dish dish =super.getById(id);
        BeanUtils.copyProperties(dish,dishDto);
        return dishDto;
    }

    /**
     *  修改菜品
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public R<String> updateWithFlavor(DishDto dishDto) {
        //修改菜品表
        super.updateById(dishDto);
        //修改口味表，先删除菜品对应的口味，再重新插入
        LambdaQueryWrapper<DishFlavor> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId,dishDto.getId());
        dishFlavorService.remove(wrapper);
        //得到菜品id,以及口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        Long dishId = dishDto.getId();
        flavors = flavors.stream().map((item) ->{
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavors);
        //修改套餐表中对应的菜品信息
        LambdaUpdateWrapper<SetmealDish> setmealDishWrapper = new LambdaUpdateWrapper<>();
        setmealDishWrapper.eq(SetmealDish::getDishId,dishDto.getId());
        setmealDishWrapper.set(SetmealDish::getName,dishDto.getName());
        setmealDishWrapper.set(SetmealDish::getPrice,dishDto.getPrice());
        setmealDishService.update(setmealDishWrapper);
        return R.success("菜品修改成功！");
    }

    /**
     *  新增套餐时查询菜品
     * @param dish
     * @return
     */
    @Override
    /*public R<List<Dish>> getWithSetmeal(Dish dish) {
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
        wrapper.like(dish.getName() != null,Dish::getName,dish.getName());
        wrapper.eq(Dish::getStatus,1);
        wrapper.orderByAsc(Dish::getSort).orderByAsc(Dish::getUpdateTime);
        List<Dish> dishList = super.list(wrapper);
        return R.success(dishList);
    }*/
    public R<List<DishDto>> getWithSetmeal(Dish dish) {
        List<DishDto> dishDtoList = null;
        //动态构造key
        String key = "dish_"+dish.getCategoryId()+"status_"+dish.getStatus();
        //查询redis中是否存在菜品
        dishDtoList  = (List<DishDto>) redisTemplate.opsForValue().get(key);
        if (dishDtoList != null){
            //redis缓存中存在
            return R.success(dishDtoList);
        }
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
        wrapper.like(dish.getName() != null,Dish::getName,dish.getName());
        wrapper.eq(Dish::getStatus,1);
        wrapper.orderByAsc(Dish::getSort).orderByAsc(Dish::getUpdateTime);
        List<Dish> dishList = super.list(wrapper);
        dishDtoList = dishList.stream().map((item) ->{
            //先将基本的菜品信息进行拷贝
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item,dishDto);
            //查询每一个菜品对应的口味
            Long dishId = item.getId();
            LambdaQueryWrapper<DishFlavor> flavorWrapper = new LambdaQueryWrapper<>();
            flavorWrapper.eq(DishFlavor::getDishId,dishId);
            List<DishFlavor> dishFlavorList = dishFlavorService.list(flavorWrapper);
            dishDto.setFlavors(dishFlavorList);
            return dishDto;
        }).collect(Collectors.toList());
        //redis缓存中不存在，则查询后存入缓存
        redisTemplate.opsForValue().set(key,dishDtoList,60, TimeUnit.MINUTES);
        return R.success(dishDtoList);
    }

    /**
     *  (批量)删除菜品
     * @param ids 要删除的菜品ID(数组)
     * @return
     */
    @Override
    @Transactional
    public void deleted(List<Long> ids) {
        //判断菜品是否处于启售状态，如果处于启售状态，则不能删除
        LambdaQueryWrapper<Dish> dishWrapper = new LambdaQueryWrapper<>();
        dishWrapper.in(Dish::getId,ids);
        dishWrapper.eq(Dish::getStatus,1);
        int count = count(dishWrapper);
        if(count > 0){
            throw new CustomerException("菜品处于起售状态，不能删除！");
        }
        //菜品处于停售状态，判断菜品是否有关联套餐，有则不能删除
        LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
        setmealDishWrapper.in(SetmealDish::getDishId,ids);
        int count1 = setmealDishService.count(setmealDishWrapper);
        if(count1 > 0){
            throw new CustomerException("该菜品已关联相关套餐，不能删除！");
        }
        //可以删除，同时删除该菜品的口味表
        this.removeByIds(ids);
        //删除菜品口味表的数据
        LambdaQueryWrapper<DishFlavor> flavorWrapper = new LambdaQueryWrapper<>();
        flavorWrapper.in(DishFlavor::getDishId,ids);
        dishFlavorService.remove(flavorWrapper);
    }

    /**
     *  修改菜品状态
     * @param status 要修改的状态
     * @param ids  要修改的菜品ID
     * @return
     */
    @Override
    public void updateWithStatus(Integer status, List<Long> ids) {
        Dish dish = new Dish();
        dish.setStatus(status);
        for (Long id : ids) {
            dish.setId(id);
            System.out.println(dish);
            this.updateById(dish);
        }
    }
}
